package cn.lwj.controller;

import cn.lwj.common.R;
import cn.lwj.dto.DishDto;
import cn.lwj.pojo.Category;
import cn.lwj.pojo.Dish;
import cn.lwj.pojo.DishFlavor;
import cn.lwj.service.CategoryService;
import cn.lwj.service.DishFlavorService;
import cn.lwj.service.DishService;
import com.alibaba.druid.support.spring.stat.BeanTypeAutoProxyCreator;
import com.alibaba.druid.util.StringUtils;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.NamedBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CachePut;
import org.springframework.data.redis.core.ListOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.awt.*;
import java.awt.datatransfer.FlavorEvent;
import java.lang.annotation.ElementType;
import java.util.IllegalFormatFlagsException;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collector;
import java.util.stream.Collectors;


@Slf4j
@RestController
@RequestMapping("/dish")
public class DishController {

    @Autowired
    DishService dishService;

    @Autowired
    DishFlavorService dishFlavorService;

    @Autowired
    CategoryService categoryService;

    @Autowired
    private RedisTemplate redisTemplate;

    /**
     * 新增菜品
     * @param dishDto
     * @return
     */
    @PostMapping
    public R<String> save(@RequestBody DishDto dishDto){
//        dto 全称 data transfer object 数据访问对象 用来封装传输过来的数据
        dishService.saveDishWithDishFlavor(dishDto);
        //        删除单个菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);
        return R.success("菜品保存成功");
    }

    /**
     * 分页查询
     * @param page
     * @param pageSize
     * @param name
     * @return
     */
    @GetMapping("/page")
    public R<Page> page(Integer page,Integer pageSize,String name){
//        分页构造器
        Page<Dish> pageinfo = new Page<>(page,pageSize);
        Page<DishDto> pageinfoDto = new Page<>(page,pageSize);
//        条件查询对象
        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.like( name!=null,Dish::getName,name);
        lqw.orderByAsc(Dish::getPrice);
//        分页查询
        dishService.page(pageinfo,lqw);
//        将查询到的出records之外的数据拷贝给dishDto records单独处理
        BeanUtils.copyProperties(pageinfo,pageinfoDto,"records");
        List<Dish> records = pageinfo.getRecords();
        List<DishDto> dishDtoList = records.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            Category category = categoryService.getById(item.getCategoryId());
            dishDto.setCategoryName(category.getName());
            return dishDto;
        }).collect(Collectors.toList());

        pageinfoDto.setRecords(dishDtoList);

        return R.success(pageinfoDto);
    }

    /**
     * 根据id查询菜品
     * @param id
     * @return
     */
    @GetMapping("/{id}")
    public R<DishDto> getById(@PathVariable String id){
        log.info("菜品ID：");
        log.info(id);

//        根据id查询菜品信息
        Dish dish = dishService.getById(id);
        DishDto dishDto = new DishDto();
//        将菜品信息复制至dishDto对象中
        BeanUtils.copyProperties(dish,dishDto);
//        根据id查询菜品口味信息
        LambdaQueryWrapper<DishFlavor> lqw = new LambdaQueryWrapper<>();
        lqw.eq(DishFlavor::getDishId,id);
        List<DishFlavor> list = dishFlavorService.list(lqw);
//        将口味信息添加至dishDto对象当中 响应给前端
        dishDto.setFlavors(list);
        return R.success(dishDto);
    }


    /**
     * 修改菜品以及菜品口味信息
     * @param dishDto
     * @return
     */
    @PutMapping
    public R<String> update(@RequestBody DishDto dishDto){
            dishService.updateDish(dishDto);

//            删除全部菜品相关缓存数据
        /*Set keys = redisTemplate.keys("dish_*");
        redisTemplate.delete(keys);*/

//        删除单个菜品缓存数据
        String key = "dish_" + dishDto.getCategoryId() + "_1";
        redisTemplate.delete(key);

        return R.success("修改成功");
    }

    /**
     * 删除菜品
     * @param ids
     * @return
     */
    @DeleteMapping
    public R<String> delete(String ids){
        System.out.println(ids);
//        还是操作两张表 需要重新编写业务层方法 并添加事务
        dishService.deleteDish(ids);
        return R.success("删除成功");
    }


    /**
     * 起售 停售
     * @param statusCode
     * @param ids
     * @return
     */
    @PostMapping("/status/{statusCode}")
    public R<String> updateStatus(@PathVariable int statusCode,String ids){
        dishService.updateStatus(statusCode,ids);
        return R.success("操作成功");
    }


    /**
     * 通过分类id获取菜品
     * @param dish
     * @return
     */
    @GetMapping("/list")
    public R<List<DishDto>> list(Dish dish){

//        log.info(dishDto.toString());
        List<DishDto> dishDtoList = null;

//        加入缓存功能 降低数据库的访问压力
//        先从数据库里寻找 看是否可以找到对应数据 可以找到直接返回 找不到则查询 并保存起来

        String key = "dish_" + dish.getCategoryId() + "_" + dish.getStatus();

        dishDtoList = (List<DishDto>) redisTemplate.opsForValue().get(key);

        if (dishDtoList != null) {
//            说明查询到了 直接返回即可
            log.info("{} === 已缓存无需查询数据库",key);
            return R.success(dishDtoList);
        }

        LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dish::getCategoryId,dish.getCategoryId());
        lqw.eq(Dish::getStatus,1); // 售卖状态为起售才可以选择 （业务相关）
        List<Dish> dishes = dishService.list(lqw);
        dishDtoList = dishes.stream().map((item) -> {
            DishDto dishDto = new DishDto();
            BeanUtils.copyProperties(item, dishDto);
            LambdaQueryWrapper<DishFlavor> dishFlavorLambdaQueryWrapper = new LambdaQueryWrapper<>();
            dishFlavorLambdaQueryWrapper.eq(DishFlavor::getDishId, item.getId());
            List<DishFlavor> list = dishFlavorService.list(dishFlavorLambdaQueryWrapper);
            dishDto.setFlavors(list);
            return dishDto;
        }).collect(Collectors.toList());

//        获取数据完毕 将获取到的数据存储到redis数据库当中 下一次就可以直接获取

//        将查询到的数据存储到redis  并设置存活时间为一个小时
        redisTemplate.opsForValue().set(key,dishDtoList,1, TimeUnit.HOURS);

        return R.success(dishDtoList);
//        return R.success(dishes);

        /*LambdaQueryWrapper<Dish> lqw = new LambdaQueryWrapper<>();
        lqw.eq(Dish::getCategoryId,dishDto.getCategoryId());
        List<Dish> dishes = dishService.list(lqw);
        List<DishDto> dishDtos = dishes.stream().map((item)->{
            DishDto dto = new DishDto();
            LambdaQueryWrapper<DishFlavor> dflqw = new LambdaQueryWrapper<>();
            dflqw.eq(DishFlavor::getDishId,item.getId());
            List<DishFlavor> flavors = dishFlavorService.list(dflqw);
            dto.setFlavors(flavors);
            return dto;
        }).collect(Collectors.toList());
        return R.success(dishDtos);*/
    }




}
